#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G09 -- S00 ------------------------------------------------------------##
__docformat__ = "restructuredtext en"

from .. import formlib as layout
from .. import pilelib as stack
from .. import quickplayscore as quickplay
from .. import stackfill as fill
from ..gamelib import state, info as _gi, game
from ..hint import CautiousDefaultHint
from ..packlib import place, info as _ci
from ..forms import fortythieves as FortyThievesLayout
from ..piles import spider
from ..utillib.misc import kwdefault

GT, SL = _gi.GT, _gi.SL
Wrap = stack.StackWrapper


class Diplomat(game.Game):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation,no offset]
        - talon [1 SE, no offset]
        - waste [1 W talon, no offset]
        - foundation [8 horz NE, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.RK_RowStack (max_move=1)
        Init deal 4 open card. Build down in rank alone. Play top.

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=149, name='Diplomat', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.BALANCED,
                    version='3.30')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = FortyThievesLayout.FortyThievesLayout
    _talon_ = stack.WasteTalon
    _waste_ = stack.WasteStack
    _foundations_ = (stack.SS_Foundation,) * 2
    _row_ = Wrap(stack.RK_RowStack, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8, playcards=12, wastecards=0, texts=True)
             -> Layout
        """
        kwdefault(kw, rows=8, playcards=12, wastecards=0, texts=True)
        return super(Diplomat, self)._create_game(**kw)

    def _start(self, flip=True, rows=4, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: *rows* ea *flip*.

        .. \_start([flip=True, rows=4]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class LadyPalk(Diplomat):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation,no offset]
        - talon [1 SE, no offset]
        - waste [1 W talon, no offset]
        - foundation [8 horz NE, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.RK_RowStack
        Init deal 4 open card. Build down in rank alone. Play seq.

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=151, name='Lady Palk', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.BALANCED,
                    version='3.30')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.RK_RowStack


class Dieppe(LadyPalk):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation,no offset]
        - talon [1 SE, no offset]
        - waste [1 W talon, no offset]
        - foundation [8 horz NE, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.RK_RowStack
        Init deal 3 open card. Build down in rank alone. Play seq.

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=485, name='Dieppe', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, rows=3, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: *rows* ea open. drop w/ replace.

        .. \_start([rows=3]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].deal_row_and_drop(ncards=_ci.MAX, frames=0)
        self.s['talon'].deal_row_and_drop(ncards=_ci.MAX)


class RowsOfFour(Diplomat):
    """
    Finish cards on _foundation_ within 3 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SE, no offset]
        - waste [1 W talon, no offset]
        - foundation [8 horz NE, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.RK_RowStack (max_move=1)
        Init deal 4 open card. Build down in rank alone. Play top.

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon (max_rounds=3)
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=433, name='Rows of Four', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=2, skill_level=SL.BALANCED,
                    version='0.91fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=3)


class LittleNapoleon(Diplomat):
    """
    Finish cards on _foundation_ within 3 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.fortythieves.FortyThievesLayout
        - row [8 horz S foundation, vert offset]
        - talon [1 SE, no offset]
        - waste [1 W talon, no offset]
        - foundation [8 horz NE, no offset]

      _row_ : pysollib.stack.Stack
        .. spider.SS_RK_RowStack
        Init deal 4 open card. Build down in rank alone. Play seq by same
        suit.

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. spider.Hint
    _row_
      Init deal 4 card. Build down in rank alone. Play seq by
      same suit.

    _talon_
      Deal 1 card on _row_.

    _waste_
      Init deal 1 card. Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    """
    __info__ = dict(id=489, name='Little Napoleon',
                    game_type=GT.FORTY_THIEVES, decks=2, redeals=0,
                    skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = spider.SS_RK_RowStack
    _hint_ = spider.Hint

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: *rows* ea top open.

        .. \_start([flip=False, rows=4]) -> None
        """
        kw.setdefault('flip', False)
        super(LittleNapoleon, self)._start(**kw)

    _quickplay_ = quickplay.Spider


class Congress(Diplomat):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.CongressLayout
        - row [4 vert E foundation, 4 vert W Foundation,no offset]
        - talon [1 NW, no offset]
        - waste [1 E talon, no offset]
        - foundation [1 vert E over NSUIT col, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.RK_RowStack (max_move=1)
        Init deal 1 card. Build down in rank alone. Play top. Gap play 1 card
        from _talon_

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation
        Build up in rank by same suit. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=150, name='Congress', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.MOSTLY_SKILL,
                    version='3.30')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.CongressLayout

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(ncols=2, playcards=0) -> Layout
        """
        kwdefault(kw, ncols=2, playcards=0)
        return super(Congress, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: *rows* ea open.

        .. \_start([flip=True, rows=1]) -> None
        """
        kw.setdefault('rows', 1)
        super(Congress, self)._start(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        fill.fromWaste(self, stack, self.s['rows'])


class Parliament(Congress):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.CongressLayout
        - row [4 vert E foundation, 4 vert W Foundation,no offset]
        - talon [1 NW, no offset]
        - waste [1 E talon, no offset]
        - foundation [1 vert N over NSUIT col, no offset]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.WasteTalon
        Pile 1 W. Deal 1 card on _row_.

      _waste_ : pysollib.stack.Stack
        .. pysollib.stack.Waste
        Pile 1 E _talon_. Init deal 1 card. Build none. Play top.

      _foundation_ : pysollib.stack.Stack
        .. pysollib.stack.SS_Foundation
        Pile 8 over 2 cols. Init deal base ACE. Build up in rank by same suit.
        Play top.

      _row_ : pysollib.stack.Stack
        .. pysollib.stack.RK_RowStack (max_move=1)
        Pile 8 1 col E 1 col W _foundation_. Init deal 1 card. Build down in
        rank alone. Play top. Gap play 1 card from _talon_

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.CautiousDefaultHint
    """
    __info__ = dict(id=548, name='Parliament', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to returns ACE on top by rank, suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAce)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: 1 ea open.
          - s[rows]: *rows* ea open.

        .. \_start([flip=True, rows=4]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(Parliament, self)._start(**kw)


class Wheatsheaf(Congress):
    """
    Finish cards on _foundation_ within 1 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.CongressLayout
        - row [4 vert E foundation, 4 vert W Foundation,no offset]
        - talon [1 NW, no offset]
        - waste [1 E talon, no offset]
        - foundation [1 vert E over NSUIT col, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.UD_SS_RowStack
        Init deal 1 card. Build either in rank by same suit. Play top. Gap
        play 1 card from _talon_

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation, stack.SS_Foundation (base_rank=KING, dir=-1)
        Build in rank by same suit. E up. W down. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=549, name='Wheatsheaf', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=0, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundations_ = (stack.SS_Foundation,
                     Wrap(stack.SS_Foundation, base_rank=_ci.KING, dir=-1),)
    _row_ = stack.UD_SS_RowStack


class TwinQueens(Congress):
    """
    Finish cards on _foundation_ within 2 turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.CongressLayout
        - row [4 vert E foundation, 4 vert W Foundation,no offset]
        - talon [1 NW, no offset]
        - waste [1 E talon, no offset]
        - foundation [1 vert E over NSUIT col, no offset]

      _row_ : pysollib.stack.Stack
        .. stack.SS_RowStack (max_move=1)
        Init deal 1 card. Build down in rank by same suit. Play top. Gap play
        1 card from _talon_

      _talon_ : pysollib.stack.Stack
        .. stack.WasteTalon
        Deal 1 card on _waste_.

      _waste_ : pysollib.stack.Stack
        .. stack.Waste
        Init deal 1 card. Build none. Play top.

      _foundations_ : pysollib.stack.Stack
        .. stack.SS_Foundation (base_rank=KING,mod=13)
        Build up in rank by same suit wrap. Play top.

      _hint_ : pysollib.hint.AbstractHint
        .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=563, name='Twin Queens', game_type=GT.FORTY_THIEVES,
                    decks=2, redeals=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)
    _foundations_ = (Wrap(stack.SS_Foundation, base_rank=_ci.KING,
                                  mod=13),) * 2
    _row_ = Wrap(stack.SS_RowStack, max_move=1)


PROVIDES = [Diplomat, LadyPalk, Congress, RowsOfFour, Dieppe, LittleNapoleon,
            Parliament, Wheatsheaf, TwinQueens]